<?php

/**
 * 作者：云喵软件开发工作室
 * 官网：https://www.meoyun.com
 */

namespace app\api\controller;

use app\model\PlatformConfigModel;
use app\service\WeChatMnpService;
use support\exception\BusinessException;
use support\Request;
use support\Response;
use Respect\Validation\Validator as v;
use Respect\Validation\Exceptions\ValidationException;
use app\model\UsersModel;
use support\Redis;
use Ramsey\Uuid\Uuid;
use app\service\EmailService;

/**
 * 权限控制器
 */
class Auth extends BaseApi
{

    //账号密码登录
    public function accountLogin(Request $request): Response
    {
        try {
            $params = v::input($request->post(), [
                'username' => v::notEmpty()->setName('用户名'),
                'password' => v::notEmpty()->setName('密码')
            ]);
        } catch (ValidationException $e) {
            return $this->fail($e->getMessage());
        }

        // 查询用户信息
        $user = UsersModel::where('username', $params['username'])
            ->orWhere('email', $params['username'])
            ->first();

        if (!$user) {
            return $this->fail('用户名或密码错误！');
        }

        // 验证密码
        if (!password_verify($params['password'], $user->password)) {
            return $this->fail('用户名或密码错误！');
        }

        // 生成UUID7 token
        $token = Uuid::uuid7()->toString();

        Redis::setEx($token, 7 * 24 * 3600, $user->id);

        // 返回登录成功信息
        return $this->success([
            'token' => $token,
            'user' => $user
        ], '登录成功');
    }

    //发送邮箱验证码
    public function sendEmailCode(Request $request)
    {
        try {
            $params = v::input($request->post(), [
                'email' => v::Email()->setName('邮箱'),
            ]);
        } catch (ValidationException $e) {
            return $this->fail($e->getMessage());
        }

        $captcha = rand(100000, 999999);

        Redis::setEx($captcha, 5 * 60, $params['email']);

        EmailService::sendEmail($params["email"], "验证码", '验证码:' . $captcha);

        return $this->success();
    }

    public function accountRegister(Request $request): Response
    {
        try {
            $params = v::input($request->post(), [
                'username' => v::notEmpty()->setName('用户名'),
                'email' => v::Email()->setName('邮箱'),
                'password' => v::notEmpty()->length(6, null)->setName('密码'),
                'code' => v::notEmpty()->length(6, 6)->setName('验证码')
            ]);
        } catch (ValidationException $e) {
            return $this->fail($e->getMessage());
        }

        // 验证邮箱验证码
        $storedEmail = Redis::get($params['code']);
        if (!$storedEmail || $storedEmail !== $params['email']) {
            return $this->fail('验证码错误或已过期！');
        }

        // 检查用户名是否已存在
        $existingUser = UsersModel::where('username', $params['username'])->first();
        if ($existingUser) {
            return $this->fail('用户名已存在！');
        }

        // 检查邮箱是否已存在
        $existingEmail = UsersModel::where('email', $params['email'])->first();
        if ($existingEmail) {
            return $this->fail('邮箱已被注册！');
        }


        // 创建新用户
        $user = new UsersModel;
        $user->username = $params['username'];
        $user->nickname = '用户_' . time();
        $user->email = $params['email'];
        $user->password = password_hash($params['password'], PASSWORD_DEFAULT);
        $user->sn = $this->generateUniqueSn();
        $user->save();

        // 删除已使用的验证码
        Redis::del($params['code']);

        return $this->success();
    }

    /**
     * 生成唯一的11位SN
     * 使用时间戳后6位 + 5位随机数确保唯一性
     */
    private function generateUniqueSn(): int
    {
        // 获取当前时间戳的后6位
        $timestamp = substr(time(), -6);

        // 生成5位随机数
        $random = str_pad(rand(0, 99999), 5, '0', STR_PAD_LEFT);

        // 组合成11位数字
        $sn = intval($timestamp . $random);

        // 检查是否已存在，如果存在则递归重新生成
        if (UsersModel::where('sn', $sn)->exists()) {
            return $this->generateUniqueSn();
        }

        return $sn;
    }

    /**
     * 微信小程序登录
     */
    public function mnpLogin(Request $request): Response
    {
        try {
            $params = v::input($request->post(), [
                'code' => v::notEmpty()->setName('微信code'),
            ]);
        } catch (ValidationException $e) {
            return $this->fail($e->getMessage());
        }

        try {
            // 通过微信小程序服务获取用户信息
            $weChatService = new WeChatMnpService();
            $wechatData = $weChatService->getMnpResByCode($params['code']);

            if (!$wechatData) {
                return $this->fail('微信授权失败，请重试');
            }

            $userData = [
                'sn' => $this->generateUniqueSn(),
                'nickname' => '用户_' . time(),
                'avatar' => 'https://' .$request->header('host') .'/avatar/' .rand(1,50) . '.png'
            ];

            if (isset($wechatData['unionid'])) {
                $userData['unionid'] = $wechatData['unionid'];
            }

            // 创建或更新用户
            $user = UsersModel::firstOrCreate(['openid' => $wechatData['openid']],$userData);

            $token = Uuid::uuid7()->toString();
            $ttl = 3600 * 24 * 7; // 七天

            Redis::setex($token, $ttl, $user->id);

            // 更新登录信息
            self::updateLoginInfo($user->id);

            $user = UsersModel::find($user->id);

            return $this->success([
                'token' => $token,
                'user' => $user
            ]);
        } catch (\Exception $e) {
            return $this->fail('登录失败：' . $e->getMessage());
        }
    }

    public static function updateLoginInfo($userId): void
    {
        $user = UsersModel::find($userId);
        if (!$user) {
            throw new BusinessException('用户不存在');
        }

        $user->update([
            'last_login_time' => date('Y-m-d H:i:s'),
            'last_login_ip' => request()->getRealIp()
        ]);
    }
}
